{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**; This notebook might take some time to run since it uses the entire data downloaded for BRON. (There is a tutorial that deals with only a subset of the data in `bron_tutorial`)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Set working directory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python 3.8.2\r\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "cwd = os.path.split(os.getcwd())\n",
    "if cwd[-1] == 'tutorials':\n",
    "    os.chdir('..')\n",
    "!python --version"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Import modules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "from BRON.build_BRON import build_graph, BRON_PATH\n",
    "from path_search.path_search_BRON import main_attack\n",
    "from meta_analysis.make_data_summary import load_graph_network, main_data_summary\n",
    "from utils.bron_network_utils import load_graph_nodes\n",
    "from meta_analysis.meta_analysis_scripts.vendor_tactic_and_cvss import bron_id_to_cpe_id, cve_to_risk, make_heat_map\n",
    "from utils.tutorial_util import print_files_in_folder"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Build BRON"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Path to save BRON output\n",
    "save_path = 'full_data/full_output_data'\n",
    "os.makedirs(save_path, exist_ok=True)\n",
    "# Path to the downloaded threat information\n",
    "input_data_folder = 'download_threat_information'\n",
    "BRON_original_id_to_bron_id_path = os.path.join(save_path, BRON_PATH)\n",
    "os.makedirs(BRON_original_id_to_bron_id_path, exist_ok=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "build_graph(save_path, input_data_folder)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('full_data/full_output_data/BRON/original_id_to_bron_id/tactic_name_to_bron_id.json '\n",
      " '1608148551.606767')\n",
      "('full_data/full_output_data/BRON/original_id_to_bron_id/technique_id_to_bron_id.json '\n",
      " '1608148551.6134753')\n",
      "('full_data/full_output_data/BRON/original_id_to_bron_id/capec_id_to_bron_id.json '\n",
      " '1608148551.6285572')\n",
      "('full_data/full_output_data/BRON/original_id_to_bron_id/cwe_id_to_bron_id.json '\n",
      " '1608148566.8801901')\n",
      "('full_data/full_output_data/BRON/original_id_to_bron_id/cve_id_bron_id.json '\n",
      " '1608148567.0693045')\n",
      "('full_data/full_output_data/BRON/original_id_to_bron_id/cpe_id_bron_id.json '\n",
      " '1608148567.4512568')\n"
     ]
    }
   ],
   "source": [
    "print_files_in_folder(BRON_original_id_to_bron_id_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Structure of BRON"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each entry of threat data is a node in BRON that has 4 attributes. The node has a unique name in BRON of the form (threat data type)\\_(unique 5 digit id) where the threat data type is either Tactic, Technique, CAPEC, CWE, CVE, or CPE.\n",
    "\n",
    "There are 4 attributes for each node:\n",
    "- Original_id: ID of threat data in MITRE/NIST if it exists\n",
    "- Datatype: One of Tactic, Technique, CAPEC, CWE, CVE, or CPE\n",
    "- Name: Name of threat data in MITRE/NIST if it exists\n",
    "- Metadata: Any additional information that is contained in MITRE/NIST "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Find paths in BRON"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tactic</th>\n",
       "      <th>technique</th>\n",
       "      <th>capec</th>\n",
       "      <th>cwe</th>\n",
       "      <th>cve</th>\n",
       "      <th>risk_score</th>\n",
       "      <th>cpe</th>\n",
       "      <th>attack</th>\n",
       "      <th>Node Type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>{tactic_378253}</td>\n",
       "      <td>100</td>\n",
       "      <td>23</td>\n",
       "      <td>33</td>\n",
       "      <td>23887</td>\n",
       "      <td>142563.30</td>\n",
       "      <td>86893</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>{tactic_378210}</td>\n",
       "      <td>36</td>\n",
       "      <td>18</td>\n",
       "      <td>11</td>\n",
       "      <td>7440</td>\n",
       "      <td>37074.15</td>\n",
       "      <td>30929</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>{tactic_378208}</td>\n",
       "      <td>151</td>\n",
       "      <td>29</td>\n",
       "      <td>52</td>\n",
       "      <td>24181</td>\n",
       "      <td>144419.80</td>\n",
       "      <td>87238</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>14</td>\n",
       "      <td>665</td>\n",
       "      <td>579</td>\n",
       "      <td>376</td>\n",
       "      <td>154545</td>\n",
       "      <td>929015.55</td>\n",
       "      <td>221329</td>\n",
       "      <td>0.0</td>\n",
       "      <td>Total Number</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            tactic  technique  capec  cwe     cve  risk_score     cpe  attack  \\\n",
       "0  {tactic_378253}        100     23   33   23887   142563.30   86893     NaN   \n",
       "1  {tactic_378210}         36     18   11    7440    37074.15   30929     NaN   \n",
       "2  {tactic_378208}        151     29   52   24181   144419.80   87238     NaN   \n",
       "3               14        665    579  376  154545   929015.55  221329     0.0   \n",
       "\n",
       "      Node Type  \n",
       "0     connected  \n",
       "1     connected  \n",
       "2     connected  \n",
       "3  Total Number  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "starting_point_type = 'tactic'\n",
    "starting_point = f'example_data/example_input_data/starting_point_{starting_point_type}.csv'\n",
    "results_file = os.path.join(save_path, f'search_result_{starting_point_type}.csv')\n",
    "length = True\n",
    "main_attack(BRON_folder_path=save_path,\n",
    "            args_file=starting_point,\n",
    "            results_name=results_file,\n",
    "            arg_type=starting_point_type,\n",
    "            length=length)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tactic</th>\n",
       "      <th>technique</th>\n",
       "      <th>capec</th>\n",
       "      <th>cwe</th>\n",
       "      <th>cve</th>\n",
       "      <th>risk_score</th>\n",
       "      <th>cpe</th>\n",
       "      <th>attack</th>\n",
       "      <th>Node Type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>{tactic_378253}</td>\n",
       "      <td>{technique_378361, technique_378648, technique...</td>\n",
       "      <td>{capec_378912, capec_378915, capec_378914, cap...</td>\n",
       "      <td>{cwe_379040, cwe_379155, cwe_379678, cwe_37915...</td>\n",
       "      <td>{cve_679016, cve_640186, cve_589521, cve_73040...</td>\n",
       "      <td>142563.30</td>\n",
       "      <td>{cpe_540943, cpe_614529, cpe_632506, cpe_38295...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>{tactic_378210}</td>\n",
       "      <td>{technique_378592, technique_378614, technique...</td>\n",
       "      <td>{capec_378886, capec_378935, capec_378951, cap...</td>\n",
       "      <td>{cwe_378965, cwe_378968, cwe_379068, cwe_37904...</td>\n",
       "      <td>{cve_533493, cve_642920, cve_621104, cve_67726...</td>\n",
       "      <td>37074.15</td>\n",
       "      <td>{cpe_401826, cpe_540943, cpe_733737, cpe_72552...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>{tactic_378208}</td>\n",
       "      <td>{technique_378435, technique_378361, technique...</td>\n",
       "      <td>{capec_378912, capec_378949, capec_378941, cap...</td>\n",
       "      <td>{cwe_379230, cwe_379047, cwe_379040, cwe_37915...</td>\n",
       "      <td>{cve_679016, cve_640186, cve_589521, cve_73040...</td>\n",
       "      <td>144419.80</td>\n",
       "      <td>{cpe_540943, cpe_614529, cpe_632506, cpe_38295...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>14</td>\n",
       "      <td>665</td>\n",
       "      <td>579</td>\n",
       "      <td>376</td>\n",
       "      <td>154545</td>\n",
       "      <td>929015.55</td>\n",
       "      <td>221329</td>\n",
       "      <td>0.0</td>\n",
       "      <td>Total Number</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            tactic                                          technique  \\\n",
       "0  {tactic_378253}  {technique_378361, technique_378648, technique...   \n",
       "1  {tactic_378210}  {technique_378592, technique_378614, technique...   \n",
       "2  {tactic_378208}  {technique_378435, technique_378361, technique...   \n",
       "3               14                                                665   \n",
       "\n",
       "                                               capec  \\\n",
       "0  {capec_378912, capec_378915, capec_378914, cap...   \n",
       "1  {capec_378886, capec_378935, capec_378951, cap...   \n",
       "2  {capec_378912, capec_378949, capec_378941, cap...   \n",
       "3                                                579   \n",
       "\n",
       "                                                 cwe  \\\n",
       "0  {cwe_379040, cwe_379155, cwe_379678, cwe_37915...   \n",
       "1  {cwe_378965, cwe_378968, cwe_379068, cwe_37904...   \n",
       "2  {cwe_379230, cwe_379047, cwe_379040, cwe_37915...   \n",
       "3                                                376   \n",
       "\n",
       "                                                 cve  risk_score  \\\n",
       "0  {cve_679016, cve_640186, cve_589521, cve_73040...   142563.30   \n",
       "1  {cve_533493, cve_642920, cve_621104, cve_67726...    37074.15   \n",
       "2  {cve_679016, cve_640186, cve_589521, cve_73040...   144419.80   \n",
       "3                                             154545   929015.55   \n",
       "\n",
       "                                                 cpe  attack     Node Type  \n",
       "0  {cpe_540943, cpe_614529, cpe_632506, cpe_38295...     NaN     connected  \n",
       "1  {cpe_401826, cpe_540943, cpe_733737, cpe_72552...     NaN     connected  \n",
       "2  {cpe_540943, cpe_614529, cpe_632506, cpe_38295...     NaN     connected  \n",
       "3                                             221329     0.0  Total Number  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length = False\n",
    "main_attack(BRON_folder_path=save_path,\n",
    "            args_file=starting_point,\n",
    "            results_name=results_file,\n",
    "            arg_type=starting_point_type,\n",
    "            length=length)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tactic</th>\n",
       "      <th>technique</th>\n",
       "      <th>capec</th>\n",
       "      <th>cwe</th>\n",
       "      <th>cve</th>\n",
       "      <th>risk_score</th>\n",
       "      <th>cpe</th>\n",
       "      <th>attack</th>\n",
       "      <th>Node Type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>{}</td>\n",
       "      <td>{technique_378193}</td>\n",
       "      <td>{}</td>\n",
       "      <td>{}</td>\n",
       "      <td>{}</td>\n",
       "      <td>0.00</td>\n",
       "      <td>{}</td>\n",
       "      <td>NaN</td>\n",
       "      <td>connected</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>14</td>\n",
       "      <td>665</td>\n",
       "      <td>579</td>\n",
       "      <td>376</td>\n",
       "      <td>154545</td>\n",
       "      <td>929015.55</td>\n",
       "      <td>221329</td>\n",
       "      <td>0.0</td>\n",
       "      <td>Total Number</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  tactic           technique capec  cwe     cve  risk_score     cpe  attack  \\\n",
       "0     {}  {technique_378193}    {}   {}      {}        0.00      {}     NaN   \n",
       "1     14                 665   579  376  154545   929015.55  221329     0.0   \n",
       "\n",
       "      Node Type  \n",
       "0     connected  \n",
       "1  Total Number  "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "starting_point_type = 'technique'\n",
    "starting_point = f'example_data/example_input_data/starting_point_{starting_point_type}.csv'\n",
    "results_file = os.path.join(save_path, f'search_result_{starting_point_type}.csv')\n",
    "length = False\n",
    "main_attack(BRON_folder_path=save_path,\n",
    "            args_file=starting_point,\n",
    "            results_name=results_file,\n",
    "            arg_type=starting_point_type,\n",
    "            length=length)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tactic\n",
      "technique\n",
      "capec\n",
      "cwe\n",
      "cve\n",
      "cpe\n"
     ]
    }
   ],
   "source": [
    "# Path to BRON data\n",
    "BRON_path = os.path.join(save_path, 'BRON.json')\n",
    "save_folder = os.path.join(save_path, 'all_cves_all_versions')\n",
    "os.makedirs(save_folder, exist_ok=True)\n",
    "not_all_cpe_versions = False\n",
    "# Load the BRON graph\n",
    "graph = load_graph_network(BRON_path, not_all_cpe_versions)\n",
    "\n",
    "datatypes = [\"tactic\", \"technique\", \"capec\", \"cwe\", \"cve\", \"cpe\"]\n",
    "# Summarize data sources in BRON\n",
    "main_data_summary(graph=graph,\n",
    "                  save_folder=save_folder,\n",
    "                  data_types=datatypes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "tactics = 'persistence,discovery,defense-evasion,impact'\n",
    "vendors = 'ibm,mozilla,google'\n",
    "tactic_search_result_file = os.path.join(save_path, 'search_result_tactic.csv')\n",
    "plot_type = 'heatmap'\n",
    "cve_summary_path = os.path.join(save_folder, 'cve_summary.csv')\n",
    "_save_path = os.path.join(save_path, 'figures')\n",
    "_figure_path = os.path.join(save_path, 'vendor_tactics.png')\n",
    "tactics_split = tactics.split(',')\n",
    "vendors_split = vendors.split(',')\n",
    "bron_id_to_cpe_id_dict = bron_id_to_cpe_id(save_path)\n",
    "cve_to_risk_dict = cve_to_risk(cve_summary_path)\n",
    "with open(os.path.join(BRON_original_id_to_bron_id_path, 'tactic_name_to_bron_id.json'), 'r') as fd:\n",
    "    all_tactics_name_to_id = json.load(fd)\n",
    "tactic_ids = [f\"tactic_{all_tactics_name_to_id[_]}\" for _ in tactics_split]\n",
    "\n",
    "make_heat_map(tactics_split,\n",
    "              vendors_split,\n",
    "              tactic_ids,\n",
    "              tactic_search_result_file,\n",
    "              bron_id_to_cpe_id_dict,\n",
    "              save_path=_figure_path)"
   ]
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}